<?php
/**
 * NetBiz Framework
 * Copyright (C) 2005 - 2008 NetBiz
 * 
 * All rights reserved.
 */


class FRM_String
{
	/**
	 * Return the real length of an UTF8 string
	 *
	 * @access public
	 * @param string $utf8_string
	 * @return int the number of utf8 characters in the string
	*/	
	static function utf8_strlen($utf8_string)
	{
		return strlen(utf8_decode($utf8_string));
	}

	/**
	 * Checks if a string contains 7bit ASCII only
	 *
	 * @access public
	 * @param string $utf8_string
	 * @return bool 'true' if the string contains only ascii characters, 'false' otherwise
	 */
	static function utf8_is_ascii($utf8_string)
	{
		$count = strlen($utf8_string);
		for($i=0; $i++<$count;)
		{
			if(ord($utf8_string[$i]) >127) return false;
		}
		return true;
	}

	/**
	 * Escape an UTF8 string for display in an HTML page
	 * Typically, will convert only the 'special fives'
	 *    which are <,>,&,',"
	 *
	 * @access public
	 * @param string $utf8_string
	 * @return string the escaped string
	 * @see Smarty modifier named utf8_escape_html
	 */
	static function utf8_escape_html($utf8_string)
	{
		return htmlspecialchars($utf8_string,ENT_QUOTES,"UTF-8");
	}

	/**
	 * Escape an UTF8 string for use as JS litteral in HTML page
	 * Typically, will convert only the 'special fives'
	 *    which are <,>,&,'," (html parser escape)
	 * after having added slashes in front of all ' and " and \
	 * (javascript parser escape)
	 *
	 * @access public
	 * @param string $utf8_string
	 * @return string the escaped string
	 * @see Smarty modifier named utf8_escape_jshtml
	 */
	static function utf8_escape_jshtml($utf8_string)
	{
		return htmlspecialchars(preg_replace("/\r?\n/", "\\n", str_replace("<","\\x3C",addslashes($utf8_string))),ENT_QUOTES,"UTF-8");
	}

	/**
	 * Escape an UTF8 string for use as JS litteral in JS script section
	 * of an html page.
	 * Will add slashes in front of all ' and " and \, then will escape
	 * the opening tag characters '<' for avoiding problem with injected
	 * closing </SCRIPT> tag.
	 *
	 * @access public
	 * @param string $utf8_string
	 * @return string the escaped string
	 * @see Smarty modifier named utf8_escape_js
	 */
	static function utf8_escape_js($utf8_string)
	{
		return preg_replace("/\r?\n/", "\\n", str_replace("<","\\x3C",addslashes($utf8_string)));
	}

	/**
	 * Escape an UTF8 string for use as string in an XML document
	 * The escaping is compatible for both text node and attributes
	 * value.
	 *
	 * To fit with W3C recommandation on XML 1.0, we escape using UTF8 code
	 * of the entity (and not the html entity). Only the recommanded characters
	 * are escaped => &,",<,>,Carriage return and Line feed
	 *
	 * @param string $utf8_string
	 * @return string the escaped string
	 * @see Smarty modifier named utf8_escape_xml
	 * @link http://www.w3.org/TR/2006/REC-xml-20060816/
	 * @link http://www.w3.org/XML/Datamodel.html
	 */
	static function utf8_escape_xml($utf8_string)
	{
		return str_replace(array('&','"',"'",'<','>',"\r","\n"),
			array('&#38;','&#34;','&#39;','&#60;','&#62;','&#12;','&#10;'),
			$utf8_string );
	}

	/**
	 * Working utf8 substr function with no risks of cutting a >1 byte utf8 character
	 * in half.
	 *
	 * To achieve that, regexp are used with curly brace repetition of an UTF8 char regexp,
	 * it allows to read $from character, then capture $len character (max) in the second capture
	 * group, then return the whole 2nd capture group.
	 *
	 * @param string $utf8_string
	 * @param int $from the returned string will start at the start 'th position in string ,
	 *   counting from zero. If $from is negative, the full string will be returned.
	 * @param int $len If $len  is given and is positive, the string returned will contain at most $len
	 *   characters beginning from start (depending on the length of string ). If string length is less than
	 *   or equal to $from characters long, empty string will be returned. If $len is negative, the full string
	 *   will be returned. If $len is 0 or false, it is considered infinite
	 * @return string the subbed string
	 * @see Smarty modifier named utf8_substr
	 * @link http://vn.php.net/substr
	 */
	static function utf8_substr($utf8_string,$from,$len = 0)
	{
		$from = intval($from); $len = intval($len);
		$str_len = self::utf8_strlen($utf8_string);

		// treat $from parameter
		if ($from < 0)
		{
			$from += $str_len;
			if ($from < 0)
			{
				return '';
			}
		}
		// speed up the process in case the $from is too big
		elseif ($from >= $str_len)
		{
			return '';
		}
		

		// treat negative $len parameter
		if ($len < 0)
		{
			//speedup the process a little
			if ($from - $len >= $str_len)
			{
				return '';
			}
			
			$len += $str_len - $from;
		}


		return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$from.'}'.
			'((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+)'.(1?'{0,'.$len.'}':'*').').*#s',
			'$1',$utf8_string);
	}

	/**
	 * Returns the string representation of the message data.
	 *
	 * If $message is an object, _extractMessage() will attempt to extract
	 * the message text using a known method (such as a PEAR_Error object's
	 * getMessage() method).  If a known method, cannot be found, the
	 * serialized representation of the object will be returned.
	 *
	 * If the message data is already a string, it will be returned unchanged.
	 *
	 * @param  mixed $message   The original message data.  This may be a
	 *                          string or any object.
	 * @return string           The string representation of the message.
	 * @see PEAR::LOG
	 */
	function extract($message)
	{
		/*
		* If we've been given an object, attempt to extract the message using
		* a known method.  If we can't find such a method, default to the
		* "human-readable" version of the object.
		*
		* We also use the human-readable format for arrays.
		*/
		if (is_object($message)) {
		if (method_exists($message, 'tostring')) {
		$message = $message->toString();
		} else if (method_exists($message, '__tostring')) {
		if (version_compare(PHP_VERSION, '5.0.0', 'ge')) {
			$message = (string)$message;
		} else {
			$message = $message->__toString();
		}
		} else if (method_exists($message, 'getmessage')) {
		$message = $message->getMessage();
		} else {
		$message = print_r($message, true);
		}
		} else if (is_array($message)) {
			if (isset($message['message'])) {
			$message = $message['message'];
			} else {
			$message = print_r($message, true);
			}
		}
		
		/* Otherwise, we assume the message is a string. */
		return $message;
	}

	static public function capitalizeSymbol($string)
	{
		return implode('_',array_map('ucfirst',explode('_',$string)));
	}
}